package com.example.tdam;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.example.tdam.IconContextMenu.IconContextMenuItem;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity implements
	Constants, LocationListener,	OnItemClickListener {

	public static Context ctx;
	private ListView listView;
	private List<ContactBean> list = new ArrayList<ContactBean>();
	private ProgressDialog pd;	
	private int CONTEXT_MENU_ID = 1;	
	private IconContextMenu iconContextMenu = null;	
	private final int PHONE_ACTION = 1;
	private final int EMAIL_ACTION = 2;
	private final int SMS_ACTION = 3;
	private final int HISTORIAL_ACTION = 4;	
	private HistorialData historial;	
	private boolean passedCreate = true;	
	private LocationManager mgr;	
	private LocationListener locationListener;
	private Location currentLocation;
	private Handler mHandler = new Handler(Looper.getMainLooper());
	
	private void initiateDialog()
	{
		pd = new ProgressDialog(this);
		pd.setTitle("Procesando...");
		pd.setMessage("Obteniendo contactos.");
		pd.setCancelable(false);
		pd.setIndeterminate(true);
		pd.show();
	}
	
	private void endDialog()
	{
		if (pd!=null) {
			pd.dismiss();
		}
	}
	
	private void getContactsAndLoad(String contactLike, String orderBy)
	{
		//initiateDialog();
				
		ContanctAdapter mListAdapter = ((ContanctAdapter)listView.getAdapter());
		if (mListAdapter!=null)
		{
			mListAdapter.clear();
			mListAdapter.notifyDataSetChanged();
			listView.setAdapter(null);	
		}				
		
		Cursor contacts = getContentResolver().query(
				ContactsContract.Contacts.CONTENT_URI, null, null,
				null, Phone.DISPLAY_NAME + " " +  orderBy);
		
		while (contacts.moveToNext()) {
			ContactBean objContact = new ContactBean();
			
			//nombre del contacto
			String name = contacts
					.getString(contacts
							.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
			objContact.setName(name);
			
			String contactId =
	                contacts.getString(contacts.getColumnIndex(ContactsContract.Contacts._ID));
			
			objContact.setContactId(Long.parseLong(contactId));
			
			//telefonos del contacto
			Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
					ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
			
			//lleno el la lista con todos los telefonos del contacto
			while (phones.moveToNext()) {
                
				String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
	            int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
	            switch (type) {
	                case Phone.TYPE_HOME:
	                	objContact.getPhoneList().put(number, Phone.TYPE_HOME);
	                    break;
	                case Phone.TYPE_MOBILE:
	                	objContact.getPhoneList().put(number, Phone.TYPE_MOBILE);
	                    break;
	                case Phone.TYPE_WORK:
	                	objContact.getPhoneList().put(number, Phone.TYPE_WORK);
	                    break;
	                }				
            }
            phones.close();
            
            //obtengo direcciones de correo
            Cursor emailCur = getContentResolver().query( 
                    ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
                    null,
                    ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", 
                    new String[]{contactId}, null); 
            
            String email = "";
            int pos = 0;
            objContact.initializeEmailArray(emailCur.getCount());            
            while (emailCur.moveToNext()) { 
            	email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
            	objContact.getEmail()[pos] = email;
            	pos++;
            } 
            emailCur.close();            
            
            list.add(objContact);
		}
		contacts.close();

		ContanctAdapter objAdapter = new ContanctAdapter(
				MainActivity.this, R.layout.alluser_row, list);
		listView.setAdapter(objAdapter);

		if (null != list && list.size() != 0) {
			//endDialog();
		} else {
			//endDialog();
			//showToast("No hay contactos cargados!");
			Context ctx = MainActivity.getLastSetContext();
		    Toast.makeText(ctx, "No hay contactos cargados!", Toast.LENGTH_LONG).show();
		}
	}	
	
	public static Context getLastSetContext() {
        return ctx;
    }
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ctx = this;
		
		historial = new HistorialData(this);
		
		listView = (ListView) findViewById(R.id.list);
		listView.setOnItemClickListener(this);
	    
		//obtener desde las preferencias el ordenamiento para los contactos
		SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
		boolean orderByAsc = sharedPrefs.getBoolean("optOrder", false);		
		final String orderByString = orderByAsc ? "DESC" : "ASC";
		
		mHandler.post(new Runnable() {
	          public void run() {
	        	  try {					
						//un un hilo porque se traba con muchos contactos
						getContactsAndLoad(null, orderByString);		
					} catch (Exception e) {
				}
	          }
	    });
		
		//initialize();
	}

	private void showToast(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onItemClick(AdapterView<?> listview, View v, int position,
			long id) {
		ContactBean bean = (ContactBean) listview.getItemAtPosition(position);
		bean.setContactAvatar(retrieveContactPhoto(bean.getContactId())); //seteamos la imagen del contacto
		popUpHandle(bean, v);		
	}	
	
	private void popUpHandle(final ContactBean bean, View fromView)
	{
		iconContextMenu = new IconContextMenu(this, CONTEXT_MENU_ID);
		Resources res = getResources();
		Iterator<?> i = bean.getPhoneList().entrySet().iterator();
        while(i.hasNext())
        {        	
        	Map.Entry pairs = (Map.Entry)i.next();
        	Integer phoneType = (Integer)pairs.getValue();
        	switch (phoneType) {
            case Phone.TYPE_HOME:
            	iconContextMenu.addItem(res, (String)pairs.getKey(), R.drawable.phone, PHONE_ACTION);
                break;
            case Phone.TYPE_MOBILE:
            	iconContextMenu.addItem(res, (String)pairs.getKey(), R.drawable.phone, PHONE_ACTION);
            	iconContextMenu.addItem(res, (String)pairs.getKey(), R.drawable.sms, SMS_ACTION);
                break;
            case Phone.TYPE_WORK:
            	iconContextMenu.addItem(res, (String)pairs.getKey(), R.drawable.phone, PHONE_ACTION);
                break;
            }        	
        	i.remove();
        }
        iconContextMenu.addItem(res, "Historial", R.drawable.historial, HISTORIAL_ACTION);
        
        if (bean.getEmail() != null && bean.getEmail().length > 0)
        {
        	for (int j = 0; j < bean.getEmail().length; j++)
        	{        		
        		iconContextMenu.addItem(res, bean.getEmail()[j], R.drawable.chat, EMAIL_ACTION);	
        	}        	
        }        
        
        //set onclick listener for context menu
        iconContextMenu.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
			@Override
			public void onClick(IconContextMenuItem menuItem) {
				switch(menuItem.actionTag) {
					case PHONE_ACTION:						
						callPhone(menuItem.text.toString(), bean);
						break;
					case EMAIL_ACTION:
						sendEmail(menuItem.text.toString(), bean);
						break;
					case SMS_ACTION:
						sendSMS(menuItem.text.toString(), bean);
						break;
					case HISTORIAL_ACTION:
						showHistorial(bean.getContactId());
						break;
					}
			}
		});        
        showDialog(CONTEXT_MENU_ID);
	}
	
	private String getCurrentLocationString()
	{	
		if (currentLocation==null)
			return " no disponible";
		
		try {
			Geocoder gcd = new Geocoder(this, Locale.getDefault());
			List<Address> addresses;
			addresses = gcd.getFromLocation(currentLocation.getLatitude(), currentLocation.getLongitude(), 1);
			if (addresses.size() > 0) 
			    return addresses.get(0).getLocality();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return " no disponible";
	}
	
	private void callPhone(String telephone, ContactBean bean)
	{
		String ubicacion = getCurrentLocationString();
		
		guardarLog(bean.getContactId(), bean.getName(), "LLAMADA", telephone, ubicacion);
		
		Intent intent = new Intent(Intent.ACTION_DIAL);
	    intent.setData(Uri.parse("tel:"+telephone));
	    startActivity(intent);
	}
	
	private void sendEmail(String email, ContactBean bean)
	{
		String ubicacion = getCurrentLocationString();
		
		guardarLog(bean.getContactId(), bean.getName(), "EMAIL", email, ubicacion);
		
		Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + email));
		intent.setType("message/rfc822");		
		startActivity(Intent.createChooser(intent, "Enviar Email"));
	}
	
	private void sendSMS(String telephone, ContactBean bean)
	{
		String ubicacion = getCurrentLocationString();
		
		guardarLog(bean.getContactId(), bean.getName(), "SMS", telephone, ubicacion);
		
		Uri smsUri = Uri.parse("tel:" + telephone);
		Intent intent = new Intent(Intent.ACTION_VIEW, smsUri);		
		intent.setType("vnd.android-dir/mms-sms"); 
		intent.putExtra("address", telephone);
		startActivity(intent);
	}
	
	@Override
	protected void onPrepareDialog(int id, Dialog dialog)
	{
		if (passedCreate)
		{
			passedCreate = false;
		}
		else
		{
			iconContextMenu.RefreshValues(dialog);	
		}		
		super.onPrepareDialog(id, dialog);
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {		
		if (id == CONTEXT_MENU_ID) {
			return iconContextMenu.createMenu("Contacto");
		}
		return super.onCreateDialog(id);
	}

	private Bitmap retrieveContactPhoto(Long contactId) {		 
        Bitmap photo = null;
 
        try {
            InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),
                    ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId));
 
            if (inputStream != null) {
                photo = BitmapFactory.decodeStream(inputStream);
                inputStream.close();
            }            
 
        } catch (IOException e) {
            e.printStackTrace();
        }
		return photo; 
    }
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);
        return true;
    }
		
    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {                 
    	switch (item.getItemId()) {
        	case R.id.mnuOpciones:
        		openPreferencesMenu();
        		return true;
        	case R.id.mnuRegisterUser:
        		registerUser();
        		return true;
        	default:
        		return super.onOptionsItemSelected(item);
		}
    }
    
    private void registerUser(){    	
    	SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    	final String userName = sharedPrefs.getString("txtUserName", "");
    	final String password = sharedPrefs.getString("txtPassword", "");
    	final String url = sharedPrefs.getString("txtServer", "");
    	
    	if (userName != "" && userName != "Usuario...")
    	{
    		
    		mHandler.post(new Runnable() {
  	          public void run() {
  	        	try {
					HttpClient httpclient = new DefaultHttpClient();
					HttpPost httppost = new HttpPost(url);

					try {
					    
						StringEntity se = new StringEntity(
								"<action id=\"REQUEST_RANDOM_VALUE\" name=\"register-user\">" + 
								"<action-detail> " +
								"<user username=\"" + userName + "\" password=\"" + password + "\"/> " + 
								"</action-detail> " +
								"</action>" , 
						HTTP.UTF_8);
					    se.setContentType("text/xml");
					    httppost.setEntity(se);

					    HttpResponse httpresponse = httpclient.execute(httppost);
					    HttpEntity resEntity = httpresponse.getEntity();
					    
					    String val = EntityUtils.toString(resEntity);					    
					    Context ctx = MainActivity.getLastSetContext();
					    
					    Toast.makeText(ctx, val, Toast.LENGTH_LONG).show();
					} catch (ClientProtocolException e) {
					    // TODO Auto-generated catch block
					    e.printStackTrace();
					} catch (IOException e) {
					    // TODO Auto-generated catch block
					    e.printStackTrace();
					} catch (Exception e) {
					    // TODO Auto-generated catch block
					    e.printStackTrace();
					}
							
				} catch (Exception e) {
					showToast("Error al enviar solicitud");
				}
  	          }
    		});
    		
    		/*new Thread() {
				public void run() {
					
				};
			}.start();*/
    	}
    	else
    	{
    		showToast("Debe ingresar un nombre de usuario valido");
    	}
    }
    
    private void openPreferencesMenu()
    {
    	Intent i = new Intent(this, Preferences.class);
        startActivityForResult(i, 1);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
 
        switch (requestCode) {
        case 1:
        	SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    		boolean orderByAsc = sharedPrefs.getBoolean("optOrder", false);    		
    		final String orderByString = orderByAsc ? "DESC" : "ASC";
    		
    		mHandler.post(new Runnable() {
  	          public void run() {
  	        	  try {					
  						//un un hilo porque se traba con muchos contactos
  						getContactsAndLoad(null, orderByString);		
  					} catch (Exception e) {
  						//showToast("Error al enviar solicitud");
  					}
  	          }
    		});
        	
            break; 
        } 
    }
    
    private void guardarLog(Long contactId, String contactName, String accion, String direccion, String ubicacion)
    {    	
    	SQLiteDatabase db = historial.getWritableDatabase();
    	
    	ContentValues values = new ContentValues();
    	values.put(ID_CONTACTO_COLUMN, contactId);
    	values.put(NOMBRE_CONTACTO_COLUMN, contactName);
    	values.put(ACCION_COLUMN, accion);
    	values.put(DIRECCION_COLUMN, direccion);
    	values.put(UBICACION_COLUMN, ubicacion);
    	
    	db.insertOrThrow(TABLE_NAME, null, values);
    	
    	db.close();
    }
    
    private void showHistorial(Long contactId)
    {    	
    	SQLiteDatabase db = historial.getReadableDatabase();
    	
    	String sql = "";        	
    	sql = ID_CONTACTO_COLUMN + " = " + contactId.toString();
    	String[] columns = new String[] { NOMBRE_CONTACTO_COLUMN, ACCION_COLUMN, DIRECCION_COLUMN, UBICACION_COLUMN };
    	
    	Cursor historial = db.query(TABLE_NAME, columns, sql, 
    			null, null, null, null);
    	
    	ArrayList<String> hlist = new ArrayList<String>();
    	String entry = "";
    	String accion = "";
    	String contacto = "";
    	String direccion = "";
    	String ubicacion = "";
    	while (historial.moveToNext()) {
    		accion = historial.getString(historial.getColumnIndex(ACCION_COLUMN));
    		contacto = historial.getString(historial.getColumnIndex(NOMBRE_CONTACTO_COLUMN));
    		direccion = historial.getString(historial.getColumnIndex(DIRECCION_COLUMN));
    		ubicacion = historial.getString(historial.getColumnIndex(UBICACION_COLUMN));
    		entry = accion + " a " + contacto + " al " + direccion + " desde " + ubicacion;
    		hlist.add(entry);    		
    	}    	
    	db.close();
    	
    	Intent intent = new Intent(MainActivity.this, HistorialActivity.class);
    	intent.putStringArrayListExtra("historial", hlist);
        startActivity(intent);    	
    }
    
    private void initialize()
    {   
    	
    	/*locationListener = new LocationListener() {
    		public void onLocationChanged(Location location) {
    			currentLocation = location;
    		}

			public void onProviderDisabled(String arg0) {
				// TODO Auto-generated method stub
				
			}

			public void onProviderEnabled(String arg0) {
				// TODO Auto-generated method stub
				
			}

			public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
				// TODO Auto-generated method stub
				
			}
    	};
    	
    	mgr = (LocationManager)getSystemService(LOCATION_SERVICE);
    	mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1, locationListener);*/
    }

	@Override
	public void onLocationChanged(Location location) {
		// TODO Auto-generated method stub
		currentLocation = location;
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		
	}
}
